﻿//o 表示音节 
//o 1表示低音
//o 2中音
//o 3高音
//p 表示休止符

//c d e f g a b 表示do re mi fa so la ti

//音符长度 1表示一拍 2表示两拍 0.5表示半拍 0.25表示四分之一拍

//上海滩的第一句 浪奔写成 o 2 e 0.5 g 0.5 a 3 演奏mi so la
//o 2 e 0.5 g 0.5 a 3 e 0.5 g 0.5 d 3 e 0.5 g 0.5

using System;
using System.Collections.Generic;
using System.Text;

namespace 设计模式
{
    class yinyue
    {
        public static void main()
        {
            playcontext context = new playcontext();
            Console.WriteLine("上海滩：");
            context.text = "t 500 o 2 e 0.5 g 0.5 a 3 e 0.5 g 0.5 d 3 e 0.5 g 0.5 d 3 e 0.5 g 0.5 a 0.5 o 3 c 1 o 2 a 0.5 g 1 c 0.5 e 0.5 d 3 ";

            expression exp = null;
            try
            {
                while (context.text.Length > 0)
                {
                    string str = context.text.Substring(0, 1);

                    switch (str)
                    {
                        case "o":
                            exp = new scale();
                            break;
                        case "c":
                        case "d":
                        case "e":
                        case "f":
                        case "g":
                        case "a":
                        case "b":
                        case "p":
                            exp = new note();
                            break;

                        case "t":
                            exp = new speed();
                            break;
                    }

                    exp.interpret(context);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            Console.Read();
        }
    }

    class playcontext
    {
        public string text;
    }

    class expression
    {
        public void interpret(playcontext context)
        {
            if (context.text.Length == 0)
            {
                return;
            }
            else
            {
                string playkey = context.text.Substring(0, 1);
                context.text = context.text.Substring(2);

                double playvalue = Convert.ToDouble(context.text.Substring(0, context.text.IndexOf(" ")));
                context.text = context.text.Substring(context.text.IndexOf(" ") + 1);

                excute(playkey, playvalue.ToString());
            }
        }


        public virtual void excute(string key, string value) { }

    }

    class note : expression
    {
        public override void excute(string key, string value)
        {
            string note = "";
            switch (key)
            {
                case "c":
                    note = "1";
                    break;
                case "d":
                    note = "2";
                    break;
                case "e":
                    note = "3";
                    break;
                case "f":
                    note = "4";
                    break;
                case "g":
                    note = "5";
                    break;
                case "a":
                    note = "6";
                    break;
                case "b":
                    note = "7";
                    break;
            }

            Console.Write("{0} ", note);
        }
    }

    class scale : expression
    {
        public override void excute(string key, string value)
        {
            string scale = "";
            switch (Convert.ToInt32(value))
            {
                case 1:
                    scale = "低音";
                    break;
                case 2:
                    scale = "中音";
                    break;
                case 3:
                    scale = "高音";
                    break;

            }
            Console.Write("{0} ", scale);
        }
    }

    class speed : expression
    {
        public override void excute(string key, string value)
        {
            string speed;
            if (Convert.ToInt32(value) < 500)
            {
                speed = "快速";
            }
            else if (Convert.ToInt32(value) >= 1000)
            {
                speed = "慢速";
            }
            else
            {
                speed = "中速";
            }

            Console.Write("{0} ", speed);
        }
    }


}
